package edu.scsu.csci.config;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;

import javax.servlet.ServletException;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import edu.scsu.csci.logging.ILogger;


/**
 * Configures XStream to read the configuration file.
 * 
 * @author Maqbool Khan
 * @since jdk 1.5
 * @see
 * @viz.diagram XStreamConfig.tpx
 */
public class XStreamConfig {
	
	/**
	 * xstream instance.
	 */
	private XStream xstream;
	
	/**
	 * Constructs an xstream reader
	 */
	public XStreamConfig() {
		this.xstream = new XStream(new DomDriver());
		this.xstream.registerConverter(new ConverterXmlConverter());
		this.xstream.registerConverter(new ValidatorXmlConvertor());
		xstream.alias("converter", ConfigConvertorWrapper.class);
		xstream.alias("validator", ConfigValidatorWrapper.class);
	}
	
	
	/**
	 * @param stream
	 * @throws IOException
	 * @throws ConfigurationException
	 */
	public void readComponents(InputStream stream)throws IOException, ConfigurationException {
		InputStreamReader reader = new InputStreamReader(stream);
		XStream xstream = getXStream();
		ObjectInputStream in = xstream.createObjectInputStream(reader);
		while (true) {
			try {
				Item item = (Item) in.readObject();
				item.register();
			} catch (EOFException e) { 
				ILogger.LoggerFactory.getLogger().error("Finished reading the config file");
				break;
			} catch (ClassNotFoundException e) {
				throw new ConfigurationException(e.getMessage(), e);
			}
		}
		in.close();
		reader.close();
	}
	
	/**
	 * Configures the framework.
	 * 
	 * @throws ConfigurationException
	 * @throws IOException
	 */
	public void configure() throws ConfigurationException, IOException {
		readComponents(getXMLFile());
	}
	
	/**
	 * @return
	 * @throws ServletException
	 * @throws ConfigException
	 */
	public InputStream getXMLFile() throws ConfigurationException {
		InputStream file = XStreamConfig.class
		.getResourceAsStream("/webconfig.xml");
		if (file == null) {
			throw new ConfigurationException("The frame work has not been configured. Please provide a web-config.xml file.?");
		}
		return file;
	}
	
	/**
	 * Returns the xstream instance
	 * 
	 * @return the instance
	 */
	private XStream getXStream() {
		return xstream;
	}
	
	public static void main(String args[]){
		XStreamConfig config = new XStreamConfig();
		InputStream xmlFile = config.getXMLFile();
		try {
			config.readComponents(xmlFile);
		}
		catch (Throwable e) {e.printStackTrace();	}
		
		//fileTest();
		
	}
	
	public static void fileTest(){
		try
		{
			XStream xstream = new XStream(new DomDriver());
			xstream.registerConverter(new ConverterXmlConverter());
			xstream.registerConverter(new ValidatorXmlConvertor());
			xstream.alias("convertor", ConfigConvertorWrapper.class);
			xstream.alias("validator", ConfigValidatorWrapper.class);
			/*FileWriter writer = new FileWriter("webconfig.xml");
			 ObjectOutputStream out = xstream.createObjectOutputStream(writer, "WebConfig");
			 out.writeObject(new ConfigConvertorWrapper(String.class, StringConverter.class));
			 out.writeObject(new ConfigConvertorWrapper(Integer.class, SimpleIntegerConverter.class));
			 out.writeObject(new ConfigConvertorWrapper(Integer.class, SimpleIntegerConverter.class));
			 out.writeObject(new ConfigValidatorWrapper(String.class, StringConverter.class, AIntegerValidator.class));
			 out.writeObject(new ConfigValidatorWrapper(String.class, StringConverter.class, AStringValidator.class));
			 out.close();*/
			
			InputStream file = XStreamConfig.class
			.getResourceAsStream("/webconfig.xml");
			if (file == null) {
				throw new ConfigurationException("The frame work has not been configured. Please provide a web-config.xml file.?");
			}
			InputStreamReader reader = new InputStreamReader(file);
			ObjectInputStream in = xstream.createObjectInputStream(reader);
			/*FileReader reader = new FileReader("webconfig.xml");
			 ObjectInputStream in = xstream.createObjectInputStream(reader);*/
			while (true) {
				try {
					Item a = (Item)in.readObject();
					a.register();
					//System.out.println(a.register());
					//item.register();
				} catch (EOFException e) {
					//logger.debug("finished reading file");
					System.out.println("Finished reading file.");
					break;
				} catch (ClassNotFoundException e) {
					throw new ConfigurationException(e.getMessage(), e);
				}
			}
			
			
			
		}catch (Exception e) { e.printStackTrace();}
		
	}
}
